package com.uduemc.biso.node.web.api.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.uduemc.biso.core.common.extities.ctemplatelistdata.CTemplateItemData;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.extities.center.Template;
import com.uduemc.biso.core.utils.CryptoJava;
import com.uduemc.biso.core.utils.FileZip;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.core.utils.TemplateUtil;
import com.uduemc.biso.node.core.common.feign.CTemplateFeign;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.web.api.service.HostService;
import com.uduemc.biso.node.web.api.service.TemplateInitService;

import cn.hutool.core.io.FileUtil;

@Service
public class TemplateInitServiceImpl implements TemplateInitService {

	private static Logger logger = LoggerFactory.getLogger(TemplateInitServiceImpl.class);

	@Autowired
	private HostService hostServiceImpl;

	@Autowired
	private GlobalProperties globalProperties;

	@Autowired
	private CTemplateFeign cTemplateFeign;

	@Override
	public String zipPath(long templateId, String version) throws Exception {
		String templatePath = globalProperties.getSite().getTemplatePath();
		String zipPath = TemplateUtil.zipPath(templatePath, templateId, version);
		File file = new File(zipPath);
		if (!file.isFile()) {
			// 清空模板目录操作
			File zipDirectory = file.getParentFile();
			if (zipDirectory.isDirectory()) {
				FileUtil.del(zipDirectory);
			}

			// 进行下载操作
			String senversion = CryptoJava.en(version);
			String stemplateId = String.valueOf(templateId);
			String downloadLink = globalProperties.getCenter().makeApiTemplateDownloadLink(senversion, stemplateId);

			HttpGet httpGet = new HttpGet(downloadLink);
			HttpClient httpClient = HttpClients.createDefault();

			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity entity = httpResponse.getEntity();
			Header contentType = entity.getContentType();
			if (contentType == null) {
				logger.error("下载模板失败！" + templateId + "|" + version + " | 下载地址： " + downloadLink);
				return null;
			}
			String value = contentType.getValue();
			if (!value.equals("application/x-download")) {
				logger.error("下载模板失败！" + templateId + "|" + version + " | 下载地址： " + downloadLink);
				return null;
			}
			File parentFile = file.getParentFile();
			if (!parentFile.isDirectory()) {
				FileUtil.mkdir(parentFile);
			}
			// 创建临时下载文件名
			File fileTmp = new File(zipPath + ".tmp");
			// 创建并下载
			fileTmp.createNewFile();
			try (OutputStream out = new FileOutputStream(fileTmp); InputStream in = entity.getContent();) {
				byte[] buffer = new byte[4096];
				int readLength = 0;
				while ((readLength = in.read(buffer)) > 0) {
					byte[] bytes = new byte[readLength];
					System.arraycopy(buffer, 0, bytes, 0, readLength);
					out.write(bytes);
				}
				out.flush();
			}
			// 下载完毕后修改文件名
			FileUtil.rename(fileTmp, FileUtil.getName(file), true);

		}
		if (new File(zipPath).isFile()) {
			return zipPath;
		}
		return null;
	}

	@Override
	public String zipPath(Template template) throws Exception {
		return zipPath(template.getId(), template.getVersion());
	}

	@Override
	public String zipPath(CTemplateItemData cTemplateItemData) throws Exception {
		return zipPath(cTemplateItemData.getTemplateId(), cTemplateItemData.getVersion());
	}

	@Override
	public String copyAndUnzip(String zipPath, long hostId, long siteId) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		Host host = hostServiceImpl.getInfoById(hostId);
		return copyAndUnzip(zipPath, host, siteId);
	}

	@Override
	public String copyAndUnzip(String zipPath, Host host, long siteId) throws IOException {
		String userTemplatePath = SitePathUtil.getUserTemplateInitPathByCode(globalProperties.getSite().getBasePath(), host.getRandomCode(), siteId);
		String userTemplateFile = userTemplatePath + "/template.zip";
		File file = new File(userTemplatePath);
		if (file.isDirectory()) {
			FileUtil.del(file);
		}
		// 创建目录
		FileUtil.mkdir(file);

		FileUtil.copy(new File(zipPath), new File(userTemplateFile), true);

		if (!FileUtil.isFile(userTemplateFile)) {
			return null;
		}

		String userTemplateUnzipPath = userTemplatePath + "/template";
		// 解压
		FileZip.decompress(userTemplateUnzipPath, userTemplateUnzipPath);

		if (!new File(userTemplateUnzipPath).isDirectory()) {
			return null;
		}
		return userTemplateUnzipPath;
	}

	@Override
	public int init(long hostId, long siteId, String templatePath) throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
		// feign 请求，传递参数执行模板初始化操作
		RestResult restResult = cTemplateFeign.write(hostId, siteId, templatePath);
		Integer data = RestResultUtil.data(restResult, Integer.class);
		if (data != null && data.intValue() == 1) {
			return 1;
		}
		return 0;
	}

}
